from collections import OrderedDict
from datetime import datetime,date,timedelta
import json
import logging
from urllib.parse import urlencode
import xlwt
import pytz
import xlrd
import time

from xlwt import *

from django.db import transaction
from django.contrib.auth.hashers import make_password
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render
from django.contrib.auth.models import ContentType, Permission, Group
from django.utils.decorators import method_decorator
from django.views import View
from django.db.models import Count
from django.http import HttpResponse, JsonResponse, Http404
from django.conf import settings
from utils.visit_info import change_info
#import qiniu
from utils.len_col import len_col,write_excel
from io import StringIO, BytesIO

from .forms import PasswdForm,SuperForm
from utils.json_fun import to_json_data
from utils.res_code import Code, error_map
from . import constants
from utils import paginator_script
# from . import forms
# from utils.fastdfs.fdfs import FDFS_Client
#from utils.secrets import qiniu_secret_info
# from apps.search.constants import SHOW_HOTNEWS_COUNT
# from doc.models import Doc
# from course.models import Course, Teacher, CourseCategory
from apps.users.models import Users
from apps.searches.models import *
# 导入日志器
logger = logging.getLogger('django')

def my_decorator(func):
    def wrapper(request, *args, **kwargs):
        print('这是定义装饰器')
        print('判断用户是否登录，是否有相关权限')
        return func(request, *args, **kwargs)
    return wrapper


class MyDecoratorMixin(object):

    # def dispatch(self, request, *args, **kwargs):
    #     return super().dispatch(request, *args, **kwargs)
    @classmethod
    def as_view(cls, *args, **kwargs):
        view = super().as_view(*args, **kwargs)
        view = my_decorator(view)
        return view

class Passwd_change(LoginRequiredMixin,View):
    """
    Passwd change
    """
    def get(self,request):
        change_info(request)
        user = getattr(request, 'user', None)
        if not user:
            return to_json_data(errno=Code.ROLEERR, errmsg='用户未登陆')
        return render(request, 'admin/index/passwd.html', locals())

    def post(self,request):
        change_info(request)
        user = getattr(request, 'user', None)
        if not user:
            return to_json_data(errno=Code.ROLEERR, errmsg='用户未登陆')
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg="参数为为空，请重新输入！")
        dict_data = json.loads(json_data.decode('utf8'))

        # 5、校验参数
        form = PasswdForm(data=dict_data)

        if form.is_valid():
            Oldpasswd = form.cleaned_data.get('Oldpasswd')
            Passwd = make_password(form.cleaned_data.get('Passwd'))
            user_queryset = Users.objects.filter(username=user)
            if user_queryset:
                user = user_queryset.first()
                if user.check_password(Oldpasswd):
                    user.password = Passwd
                    user.save(update_fields=['password'])
                    return to_json_data(errmsg='密码修改成功')
                return to_json_data(errno=Code.DATAERR, errmsg='旧密码错误')
            return to_json_data(errno=Code.NODATA, errmsg='用户不存在')
        return to_json_data(errno=Code.DATAERR, errmsg='密码校验错误')





class IndexView(LoginRequiredMixin,View):
# class IndexView(View):
    """create admin index view
    route: /admin/
    """
    # login_url = 'users:login'
    # login_url = '/users/login/'
    # @method_decorator(my_decorator)
    # def dispatch(self, request, *args, **kwargs):
    #     return super().dispatch(request, *args, **kwargs)

    # @method_decorator(my_decorator)
    def get(self, request):
        change_info(request)
        # print(IndexView.__mro__)
        user = getattr(request, 'user', None)
        if not user:
            return to_json_data(errno=Code.ROLEERR, errmsg='用户未登陆')
        users = user.username
        idcn_id = user.idcn_id
        username = user.first_name
        idcn = IdcN.objects.only("id","name").filter(is_delete=False)
        return render(request, 'admin/index/index.html',locals())

    # @method_decorator(my_decorator)
    def post(self, request):
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        user = getattr(request, 'user', None)
        username = user.username
        idcn_id = dict_data["idcn_id"]
        useres =Users.objects.only("first_name","idcn_id").filter(username=username).first()
        if useres:
            useres.idcn_id = idcn_id
            useres.save(update_fields=["idcn_id"])
        return to_json_data(errmsg='备注修改成功')


    # @method_decorator(my_decorator)
    def delete(self, request):
        pass

class Zxingtu(LoginRequiredMixin,View):
    """
    test index
    """
    # @method_decorator(login_required(login_url="users:login"))
    # @method_decorator(my_decorator)
    def get(self,request):
        change_info(request)
        try:
            start_time = request.GET.get('start_time', '')
            start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''

            end_time = request.GET.get('end_time', '')
            end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        except Exception as e:
            logger.info("用户输入的时间有误：\n{}".format(e))
            start_time = end_time = ''

            # 通过标签id进行过滤
        try:
            idcn_id = int(request.GET.get('idcn_id', 0))
        except Exception as e:
            logger.info("标签错误：\n{}".format(e))
            idcn_id = 0


        start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # 1、获取文章标签
        idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            'idcn': idcn,
            'start_time': start_time,
            "end_time": end_time,
            "idcn_id": idcn_id,
            "other_param": urlencode({
                "start_time": start_time,
                "end_time": end_time,
                "idcn_id": idcn_id,
            })
        }
        return render(request, 'admin/news/zxt.html', context=context)

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        idcn_id = dict_data["idcn_id"]
        zb = dict_data["zb"]
        jj = dict_data["jj"]
        start_time = dict_data["start_time"]
        start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        end_time = dict_data["end_time"]
        end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        useres = Users.objects.only("first_name").filter(is_active=True,idcn_id=idcn_id)
        useres1 = Users.objects.only("first_name").filter(is_active=True)
        idcn = IdcN.objects.only("id").filter(is_delete=False)
        gdes = Gd.objects.only("hcount","dc_id").filter(is_delete=False)
        dces = DesCond.objects.only("fname").filter(is_delete=False)
        #tags = DesCond.objects.values('id','fname').annotate(num_gd=Count('gd')).filter(is_delete=False).order_by('-num_gd')
        if start_time and not end_time:
            gdes = gdes.filter(update_time__lte=start_time)
        if end_time and not start_time:
            gdes = gdes.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            gdes = gdes.filter(update_time__range=(start_time, end1_time))

        if zb != "0":
            gdes = gdes.filter(zb=zb)

        if jj != "0":
            gdes = gdes.filter(jj=jj)

        if idcn_id != "0":
            idcn = idcn.filter(id=idcn_id).first()
            idc = idcn.name
            data_list = []
            data1_list = []
            data2_list = []
            data3_list = []
            data4_list = []
            z = 0
            for i in useres:
                z = z + 1
                name = i.first_name
                gdes1 = gdes.filter(cuser=name)
                hcount = 0
                for n in gdes1:
                    hcount = hcount + n.hcount
                data_list.append({
                    'idc': idc,
                    'name': name,
                    'hcount': hcount,
                })

            for i in dces:
                name = i.fname
                dc_id = i.id
                h = 0
                gdes1 = gdes.filter(dc_id=dc_id, idcn_id=idcn_id)
                for m in gdes1:
                    h = h + m.hcount
                if h != 0:
                    data1_list.append({
                        'name': name,
                        'value': h,
                    })
            a = 0
            b = 0

            for i in dces:
                name = i.fname
                dc_id = i.id
                n = 0
                h = 0
                gdes1 = gdes.filter(dc_id=dc_id, idcn_id=idcn_id)
                for m in gdes1:
                    n = n + 1
                    h = h + m.hcount
                a = a + n
                b = b + h
                data2_list.append({
                        'name': name,
                        'value': n,
                        'hcount': h,
                    })
            c = a/z
            d = b/z
            data3_list.append({
                    'all':a,
                    'hall':b,
            })
            data4_list.append({
                    'all':int(c),
                    'hall':int(d),
            })

            data = {
                'pro_inf': data_list,
                'pro1_inf': data1_list,
                'pro4_inf':data2_list,
                'pro5_inf':data3_list,
                'pro6_inf':data4_list,
            }



            return to_json_data(data=data)

        data1_list = []
        data2_list = []
        data3_list = []
        data4_list = []
        data5_list = []

        z = 0
        for i in useres1:
            z = z + 1

        for i in dces:
            name = i.fname
            dc_id = i.id
            h = 0
            gdes1 = gdes.filter(dc_id=dc_id)
            for m in gdes1:
                h = h + m.hcount
            if h != 0:
                data1_list.append({
                    'name': name,
                    'value': h,
                })
        a = 0
        b = 0
        for i in dces:
            name = i.fname
            dc_id = i.id
            n = 0
            h = 0
            gdes1 = gdes.filter(dc_id=dc_id)
            for m in gdes1:
                n = n + 1
                h = h + m.hcount
            a = a + n
            b = b + h
            data3_list.append({
                    'name': name,
                    'value': n,
                    'hcount': h,
                })
        c = a / z
        d = b / z
        data4_list.append({
            'all': a,
            'hall': b,
        })
        data5_list.append({
            'all': int(c),
            'hall': int(d),
        })

        for i in idcn:
            name = i.name
            idcn_id = i.id
            h = 0
            gdes1 = gdes.filter(idcn_id=idcn_id)
            for m in gdes1:
                h = h + m.hcount
            if h != 0:
                data2_list.append({
                    'name': name,
                    'hcount': h,
                })

        data = {
            'pro2_inf': data2_list,
            'pro3_inf': data1_list,
            'pro4_inf': data3_list,
            'pro5_inf':data4_list,
            'pro6_inf': data5_list,
        }

        return to_json_data(data=data)





    def put(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        cname = dict_data["name"]
        zb = dict_data["zb"]
        jj = dict_data["jj"]
        start_time = dict_data["start_time"]
        start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        end_time = dict_data["end_time"]
        end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        gdes = Gd.objects.only("hcount","dc_id").filter(is_delete=False)
        dces = DesCond.objects.only("fname").filter(is_delete=False)

        if start_time and not end_time:
            gdes = gdes.filter(update_time__lte=start_time)
        if end_time and not start_time:
            gdes = gdes.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            gdes = gdes.filter(update_time__range=(start_time, end1_time))

        if zb != "0":
            gdes = gdes.filter(zb=zb)

        if jj != "0":
            gdes = gdes.filter(jj=jj)

        data3_list = []

        for i in dces:
            name = i.fname
            dc_id = i.id
            n=0
            h=0
            gdes1 = gdes.filter(dc_id=dc_id,cuser=cname)
            for m in gdes1:
                n =n+1
                h = h + m.hcount
            if n != 0:
                data3_list.append({
                    'name': name,
                    'value': h,
                    'hcount':n,
                })

        data = {
            'pro3_inf':data3_list,
        }

        return to_json_data(data=data)

class Test(View):
    """
    test index
    """

    def get(self,request):
        change_info(request)
        return render(request, 'admin/news/test.html')

    def post(self, request):
        change_info(request)
        stmp = time.localtime()
        now_time = time.strftime('%Y/%m/%d',stmp)
        now_time = datetime.strptime(now_time, '%Y/%m/%d')
        yesterday = (date.today() + timedelta(days=-7)).strftime("%Y/%m/%d")
        yesterday = datetime.strptime(yesterday, '%Y/%m/%d')
        useres1 = Users.objects.only("first_name").filter(is_active=True)
        idcn = IdcN.objects.only("id").filter(is_delete=False)
        gdes = Gd.objects.only("hcount","dc_id").filter(is_delete=False)
        dces = DesCond.objects.only("fname").filter(is_delete=False)
        gds = gdes.filter(update_time__range=(yesterday, now_time))

        idcn = ["7","3","6","2","1","8","4"]

        ws = Workbook(encoding='utf-8')
        for i in idcn:
            hz = 0
            sz = 0
            id = i
            rs = 0
            useres2 = useres1.filter(idcn_id=id)
            for io in useres2:
                rs += 1
            gds1 = gds.select_related("idcn").only("idcn_id").filter(idcn_id=id)
            ds = gds1.first()
            if gds1:
                w = ws.add_sheet(str(ds.idcn.name))
                w.write(0, 0, "时间：")
                w.write(0, 1, str(yesterday)+"-"+str(now_time))
                w.write(1, 0, "工单类型")
                w.write(1, 1, "工单数量")
                w.write(1, 2, "工单耗时")
                excel_row = 2
                for obj in dces:
                    name = obj.fname
                    dc_id = obj.id
                    n = 0
                    h = 0
                    gds2 = gds1.filter(dc_id=dc_id)

                    for m in gds2:
                        n = n + 1
                        h = h + m.hcount
                    hz = hz + n
                    sz = sz + h
                    w.write(excel_row, 0, name)
                    w.write(excel_row, 1, n)
                    w.write(excel_row, 2, h)
                    excel_row += 1
                w.write(excel_row, 0 ,'合计数量')
                w.write(excel_row, 1, hz)
                w.write(excel_row, 2, sz)
                w.write(excel_row+1, 0, '人均数量')
                w.write(excel_row+1, 1, int(hz/rs))
                w.write(excel_row+1, 2, int(sz/rs))

        ws.save('test2.xls')
        print('test2创建成功')


        return to_json_data()

class NewsManageView(LoginRequiredMixin,View):
    """create news manange view
    route:  /admin/news/
    """
    permission_required = ('index.add_gd', 'index.view_gd')
    raise_exception = True


        # 4、分页操作
        # 5、模板渲染

    def get(self, request):
        change_info(request)

        # 2、从前端或取参数
        stmp = time.localtime()
        now_time = time.strftime('%Y/%m/%d', stmp)
        now_time = datetime.strptime(now_time, '%Y/%m/%d')
        yesterday = (date.today() + timedelta(days=-120)).strftime("%Y/%m/%d")
        yesterday = datetime.strptime(yesterday, '%Y/%m/%d')
        newses = Gd.objects.select_related('dc','idcn').order_by('-id').only('id', 'gname','gcount', 'hcount', 'update_time','dc_id','idcn_id','zb'). \
                filter(is_delete=False,update_time__gte=yesterday)


        # 3、通过过滤条件，去数据库中查询
        # 通过时间进行过滤
        try:
            start_time = request.GET.get('start_time', '')
            start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''

            end_time = request.GET.get('end_time', '')
            end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        except Exception as e:
            logger.info("用户输入的时间有误：\n{}".format(e))
            start_time = end_time = ''

        if start_time and not end_time:
            newses = newses.filter(update_time__lte=start_time)
        if end_time and not start_time:
            newses = newses.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            newses = newses.filter(update_time__range=(start_time, end1_time))

        # 通过标签id进行过滤
        try:
            idcn_id = int(request.GET.get('idcn_id', 0))
        except Exception as e:
            logger.info("标签错误：\n{}".format(e))
            idcn_id = 0
        if idcn_id != 0:
            newses = newses.filter(is_delete=False, idcn_id=idcn_id)

        try:
            zb_id = int(request.GET.get('zb_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            zb_id = 0

        try:
            jj_id = int(request.GET.get('jj_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            jj_id = 0

        if zb_id == 1:
            m = "5*8时间段工单"
            newses = newses.filter(zb=m)
        elif zb_id == 2:
            m = "非5*8时间段工单"
            newses = newses.filter(zb=m)

        if jj_id == 1:
            m1 = "非紧急工单"
            newses = newses.filter(jj=m1)
        elif jj_id == 2:
            m1 = "紧急工单"
            newses = newses.filter(jj=m1)

        i = 0
        for n in newses:
            i = i + 1

        # 获取第几页内容
        try:
            page = int(request.GET.get('page', 1))
        except Exception as e:
            logger.info("当前页数错误：\n{}".format(e))
            page = 1
        paginator = Paginator(newses, constants.PER_PAGE_NEWS_COUNT)
        try:
            news_info = paginator.page(page)
        except EmptyPage:
            # 若用户访问的页数大于实际页数，则返回最后一页数据
            logging.info("用户访问的页数大于总页数。")
            news_info = paginator.page(paginator.num_pages)

        paginator_data = paginator_script.get_paginator_data(paginator, news_info)

        start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # 1、获取文章标签
        idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            'number':i,
            'news_info': news_info,
            'paginator': paginator,
            'idcn':idcn,
            'start_time': start_time,
            "end_time": end_time,
            "idcn_id": idcn_id,
            "zb_id": zb_id,
            "jj_id":jj_id,
            "other_param": urlencode({
                "start_time": start_time,
                "end_time": end_time,
                "idcn_id": idcn_id,
                "zb_id":zb_id,
                "jj_id":jj_id,
            })
        }
        context.update(paginator_data)
        return render(request, 'admin/news/news_manage.html', context=context)

    def post(self,request):
        change_info(request)
        """
           导出excel表格
        """
        jsondata = request.POST
        if not jsondata:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="出入数据不能为空")
        data = json.loads(jsondata['json'])
        idcn_id = data["idcn_id"]
        zb_id = data["zb_id"]
        jj_id = data["jj_id"]
        start_time = data["start_time"]
        start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        end_time = data["end_time"]
        end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        G_obj = Gd.objects.select_related('dc', 'idcn').order_by("-id").only("dc__fname", "update_time", "idcn__name", "cuser", "gname","gcount", "hcount").filter(is_delete=False)

        if start_time and not end_time:
            G_obj = G_obj.filter(update_time__lte=start_time)
        if end_time and not start_time:
            G_obj = G_obj.filter(update_time__gte=end_time)

        if start_time and end_time:
            # end_time1 = end_time1.split("/")[0] + "/" + end_time1.split("/")[1] + "/" + str(
            #     int(end_time1.split("/")[2]) + 1)
            # end_time2 = datetime.strptime(end_time1, '%Y/%m/%d') if end_time1 else ''
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            G_obj = G_obj.filter(update_time__range=(start_time, end1_time))

        if idcn_id != "0":
            G_obj =G_obj.filter(is_delete=False,idcn_id=idcn_id)

        if zb_id != "0":
            if zb_id == "1":
                m = "5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)
            elif zb_id == "2":
                m = "非5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)

        if jj_id != "0":
            if jj_id == "1":
                m1 = "非紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)
            elif jj_id == "2":
                m1 = "紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)

        # 创建工作薄
        ws = Workbook(encoding='utf-8')
        w = ws.add_sheet(u"sheet1")
        w.write(0, 0, "工单上传时间")
        w.write(0, 1, "处理人")
        w.write(0, 2, "所属机房")
        w.write(0, 3, "工单时间段")
        w.write(0, 4, "紧急程度")
        w.write(0, 5, "工单类型")
        w.write(0, 6, "工单链接")
        w.write(0, 7, "工单量")
        w.write(0, 8, "工单耗时")

        # 写入数据
        excel_row = 1
        for obj in G_obj:
            w.write(excel_row, 0, obj.update_time.replace(tzinfo=None))
            w.write(excel_row, 1, obj.cuser)
            w.write(excel_row, 2, obj.idcn.name)
            w.write(excel_row, 3, obj.zb)
            w.write(excel_row, 4, obj.jj)
            w.write(excel_row, 5, obj.dc.fname)
            w.write(excel_row, 6, obj.gname)
            w.write(excel_row, 7, obj.gcount)
            w.write(excel_row, 8, obj.hcount)
            excel_row += 1
            # 检测文件是够存在
            #  方框中代码是保存本地文件使用，如不需要请删除该代码
            ###########################
            # exist_file = os.path.exists("test.xls")
            # if exist_file:
            #     os.remove(r"test.xls")
            # ws.save("test.xls")
            ############################
        sio = BytesIO()  # 这里原博客是StringIO.StringIO()，发现有点问题
        ws.save(sio)
        sio.seek(0)
        # final_filename = '建德内部资产.xls'
            # doc_filename = escape_uri_path(final_filename)
        response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename=gd.xls'
        response.write(sio.getvalue())
        return response
    # else:
    #     return to_json_data(errno=Code.DBERR, errmsg="未查到相应数据")

class NewstestManageView(LoginRequiredMixin,View):
    """create news manange view
    route:  /admin/news/
    """
    permission_required = ('index.add_gd', 'index.view_gd')
    raise_exception = True


        # 4、分页操作
        # 5、模板渲染

    def get(self, request):
        change_info(request)

        # 2、从前端或取参数
        newses = Gd.objects.select_related('dc','idcn').order_by('-id').only('id', 'gname','gcount', 'hcount', 'update_time','dc_id','idcn_id','zb'). \
                filter(is_delete=False)


        # 3、通过过滤条件，去数据库中查询
        # 通过时间进行过滤
        # try:
        #     start_time = request.GET.get('start_time', '')
        #     start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        #
        #     end_time = request.GET.get('end_time', '')
        #     end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        # except Exception as e:
        #     logger.info("用户输入的时间有误：\n{}".format(e))
        #     start_time = end_time = ''
        #
        # if start_time and not end_time:
        #     newses = newses.filter(update_time__lte=start_time)
        # if end_time and not start_time:
        #     newses = newses.filter(update_time__gte=end_time)
        #
        # if start_time and end_time:
        #     newses = newses.filter(update_time__range=(start_time, end_time))
        #
        # # 通过标签id进行过滤
        # try:
        #     idcn_id = int(request.GET.get('idcn_id', 0))
        # except Exception as e:
        #     logger.info("标签错误：\n{}".format(e))
        #     idcn_id = 0
        # if idcn_id != 0:
        #     newses = newses.filter(is_delete=False, idcn_id=idcn_id)
        #
        # try:
        #     zb_id = int(request.GET.get('zb_id', 0))
        # except Exception as e:
        #     logger.info("时间段错误：\n{}".format(e))
        #     zb_id = 0
        #
        # try:
        #     jj_id = int(request.GET.get('jj_id', 0))
        # except Exception as e:
        #     logger.info("时间段错误：\n{}".format(e))
        #     jj_id = 0
        #
        # if zb_id == 1:
        #     m = "5*8时间段工单"
        #     newses = newses.filter(zb=m)
        # elif zb_id == 2:
        #     m = "非5*8时间段工单"
        #     newses = newses.filter(zb=m)
        #
        # if jj_id == 1:
        #     m1 = "非紧急工单"
        #     newses = newses.filter(jj=m1)
        # elif jj_id == 2:
        #     m1 = "紧急工单"
        #     newses = newses.filter(jj=m1)
        #
        # i = 0
        # for n in newses:
        #     i = i + 1
        #
        # # 获取第几页内容
        # try:
        #     page = int(request.GET.get('page', 1))
        # except Exception as e:
        #     logger.info("当前页数错误：\n{}".format(e))
        #     page = 1
        # paginator = Paginator(newses, constants.PER_PAGE_NEWS_COUNT)
        # try:
        #     news_info = paginator.page(page)
        # except EmptyPage:
        #     # 若用户访问的页数大于实际页数，则返回最后一页数据
        #     logging.info("用户访问的页数大于总页数。")
        #     news_info = paginator.page(paginator.num_pages)
        #
        # paginator_data = paginator_script.get_paginator_data(paginator, news_info)
        #
        # start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        # end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # # 1、获取文章标签
        # idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            # 'number':i,
            'news_info': newses,
            # 'paginator': paginator,
            # 'idcn':idcn,
            # 'start_time': start_time,
            # "end_time": end_time,
            # "idcn_id": idcn_id,
            # "zb_id": zb_id,
            # "jj_id":jj_id,
            # "other_param": urlencode({
            #     "start_time": start_time,
            #     "end_time": end_time,
            #     "idcn_id": idcn_id,
            #     "zb_id":zb_id,
            #     "jj_id":jj_id,
            # })
        }
        # context.update(paginator_data)
        return render(request, 'admin/news/news_manage_test.html',context=context)

    def post(self,request):
        change_info(request)
        """
           导出excel表格
        """
        jsondata = request.POST
        if not jsondata:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="出入数据不能为空")
        data = json.loads(jsondata['json'])
        idcn_id = data["idcn_id"]
        zb_id = data["zb_id"]
        jj_id = data["jj_id"]
        start_time = data["start_time"]
        start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        end_time = data["end_time"]
        end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        G_obj = Gd.objects.select_related('dc', 'idcn').order_by("-id").only("dc__fname", "update_time", "idcn__name", "cuser", "gname","gcount", "hcount").filter(is_delete=False)

        if start_time and not end_time:
            G_obj = G_obj.filter(update_time__lte=start_time)
        if end_time and not start_time:
            G_obj = G_obj.filter(update_time__gte=end_time)

        if start_time and end_time:
            # end_time1 = end_time1.split("/")[0] + "/" + end_time1.split("/")[1] + "/" + str(
            #     int(end_time1.split("/")[2]) + 1)
            # end_time2 = datetime.strptime(end_time1, '%Y/%m/%d') if end_time1 else ''
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            G_obj = G_obj.filter(update_time__range=(start_time, end1_time))

        if idcn_id != "0":
            G_obj =G_obj.filter(is_delete=False,idcn_id=idcn_id)

        if zb_id != "0":
            if zb_id == "1":
                m = "5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)
            elif zb_id == "2":
                m = "非5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)

        if jj_id != "0":
            if jj_id == "1":
                m1 = "非紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)
            elif jj_id == "2":
                m1 = "紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)

        # 创建工作薄
        ws = Workbook(encoding='utf-8')
        w = ws.add_sheet(u"sheet1")
        w.write(0, 0, "工单上传时间")
        w.write(0, 1, "处理人")
        w.write(0, 2, "所属机房")
        w.write(0, 3, "工单时间段")
        w.write(0, 4, "紧急程度")
        w.write(0, 5, "工单类型")
        w.write(0, 6, "工单链接")
        w.write(0, 7, "工单量")
        w.write(0, 8, "工单耗时")

        # 写入数据
        excel_row = 1
        for obj in G_obj:
            w.write(excel_row, 0, obj.update_time.replace(tzinfo=None))
            w.write(excel_row, 1, obj.cuser)
            w.write(excel_row, 2, obj.idcn.name)
            w.write(excel_row, 3, obj.zb)
            w.write(excel_row, 4, obj.jj)
            w.write(excel_row, 5, obj.dc.fname)
            w.write(excel_row, 6, obj.gname)
            w.write(excel_row, 7, obj.gcount)
            w.write(excel_row, 8, obj.hcount)
            excel_row += 1
            # 检测文件是够存在
            #  方框中代码是保存本地文件使用，如不需要请删除该代码
            ###########################
            # exist_file = os.path.exists("test.xls")
            # if exist_file:
            #     os.remove(r"test.xls")
            # ws.save("test.xls")
            ############################
        sio = BytesIO()  # 这里原博客是StringIO.StringIO()，发现有点问题
        ws.save(sio)
        sio.seek(0)
        # final_filename = '建德内部资产.xls'
            # doc_filename = escape_uri_path(final_filename)
        response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename=gd.xls'
        response.write(sio.getvalue())
        return response

class Gddownload(LoginRequiredMixin,View):

    def post(self,request):
        change_info(request)
        """
           导出excel表格
        """
        jsondata = request.POST
        if not jsondata:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="出入数据不能为空")
        data = json.loads(jsondata['json'])
        user = getattr(request, 'user', None)
        username = user.first_name
        idcn_id = data["idcn_id"]
        zb_id = data["zb_id"]
        jj_id = data["jj_id"]
        start_time = data["start_time"]
        start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        end_time = data["end_time"]
        end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        G_obj = Gd.objects.select_related('dc', 'idcn').order_by("-id").only("dc__fname", "update_time", "idcn__name", "cuser", "gname","gcount", "hcount").filter(is_delete=False,cuser=username)

        if start_time and not end_time:
            G_obj = G_obj.filter(update_time__lte=start_time)
        if end_time and not start_time:
            G_obj = G_obj.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            G_obj = G_obj.filter(update_time__range=(start_time, end1_time))

        if idcn_id != "0":
            G_obj =G_obj.filter(is_delete=False,idcn_id=idcn_id)

        if zb_id != "0":
            if zb_id == "1":
                m = "5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)
            elif zb_id == "2":
                m = "非5*8时间段工单"
                G_obj = G_obj.filter(is_delete=False, zb=m)

        if jj_id != "0":
            if jj_id == "1":
                m1 = "非紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)
            elif jj_id == "2":
                m1 = "紧急工单"
                G_obj = G_obj.filter(is_delete=False, jj=m1)

        # 创建工作薄
        ws = Workbook(encoding='utf-8')
        w = ws.add_sheet(u"sheet1")
        w.write(0, 0, "工单上传时间")
        w.write(0, 1, "处理人")
        w.write(0, 2, "所属机房")
        w.write(0, 3, "工单时间段")
        w.write(0, 4, "紧急程度")
        w.write(0, 5, "工单类型")
        w.write(0, 6, "工单链接")
        w.write(0, 7, "工单量")
        w.write(0, 8, "工单耗时")

        # 写入数据
        excel_row = 1
        for obj in G_obj:
            w.write(excel_row, 0, obj.update_time.replace(tzinfo=None))
            w.write(excel_row, 1, obj.cuser)
            w.write(excel_row, 2, obj.idcn.name)
            w.write(excel_row, 3, obj.zb)
            w.write(excel_row, 4, obj.jj)
            w.write(excel_row, 5, obj.dc.fname)
            w.write(excel_row, 6, obj.gname)
            w.write(excel_row, 7, obj.gcount)
            w.write(excel_row, 8, obj.hcount)
            excel_row += 1
            # 检测文件是够存在
            #  方框中代码是保存本地文件使用，如不需要请删除该代码
            ###########################
            # exist_file = os.path.exists("test.xls")
            # if exist_file:
            #     os.remove(r"test.xls")
            # ws.save("test.xls")
            ############################
        sio = BytesIO()  # 这里原博客是StringIO.StringIO()，发现有点问题
        ws.save(sio)
        sio.seek(0)
        # final_filename = '建德内部资产.xls'
            # doc_filename = escape_uri_path(final_filename)
        response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename=grgd.xls'
        response.write(sio.getvalue())
        return response



class GdManageView(LoginRequiredMixin,View):
    """create news manange view
    route:  /admin/gd/
    """
    def get(self, request):
        change_info(request)

        # 2、从前端或取参数
        user = getattr(request, 'user', None)
        username = user.first_name
        if not username:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="查看失败,请先到后台添加正确姓名")
        newses = Gd.objects.select_related('dc','idcn').order_by('-id').only('id', 'gname', 'gcount', 'hcount', 'update_time','dc_id','idcn_id'). \
                filter(is_delete=False,cuser=username)


        # 3、通过过滤条件，去数据库中查询
        # 通过时间进行过滤
        try:
            start_time = request.GET.get('start_time', '')
            start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''

            end_time = request.GET.get('end_time', '')
            end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        except Exception as e:
            logger.info("用户输入的时间有误：\n{}".format(e))
            start_time = end_time = ''

        if start_time and not end_time:
            newses = newses.filter(update_time__lte=start_time)
        if end_time and not start_time:
            newses = newses.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            newses = newses.filter(update_time__range=(start_time, end1_time))

        # 通过标签id进行过滤
        try:
            idcn_id = int(request.GET.get('idcn_id', 0))
        except Exception as e:
            logger.info("标签错误：\n{}".format(e))
            idcn_id = 0
        if idcn_id != 0:
            newses = newses.filter(is_delete=False, idcn_id=idcn_id)

        try:
            zb_id = int(request.GET.get('zb_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            zb_id = 0

        try:
            jj_id = int(request.GET.get('jj_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            jj_id = 0

        if zb_id == 1:
            m = "5*8时间段工单"
            newses = newses.filter(zb=m)
        elif zb_id == 2:
            m = "非5*8时间段工单"
            newses = newses.filter(zb=m)

        if jj_id == 1:
            m1 = "非紧急工单"
            newses = newses.filter(jj=m1)
        elif jj_id == 2:
            m1 = "紧急工单"
            newses = newses.filter(jj=m1)

        i = 0
        for n in newses:
            i = i + 1

        # 获取第几页内容
        try:
            page = int(request.GET.get('page', 1))
        except Exception as e:
            logger.info("当前页数错误：\n{}".format(e))
            page = 1
        paginator = Paginator(newses, constants.PER_PAGE_NEWS_COUNT)
        try:
            news_info = paginator.page(page)
        except EmptyPage:
            # 若用户访问的页数大于实际页数，则返回最后一页数据
            logging.info("用户访问的页数大于总页数。")
            news_info = paginator.page(paginator.num_pages)

        paginator_data = paginator_script.get_paginator_data(paginator, news_info)

        start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # 1、获取文章标签
        idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            'number':i,
            'news_info': news_info,
            'paginator': paginator,
            'idcn':idcn,
            'start_time': start_time,
            "end_time": end_time,
            "idcn_id": idcn_id,
            "zb_id": zb_id,
            "jj_id":jj_id,
            "other_param": urlencode({
                "start_time": start_time,
                "end_time": end_time,
                "idcn_id": idcn_id,
                "zb_id": zb_id,
                "jj_id":jj_id,
            })
        }
        context.update(paginator_data)
        return render(request, 'admin/news/gd_manange.html', context=context)



    def post(self,request):
        change_info(request)
        '''
            :param request:
            :return: 上传文件excel表格 ,并进行解析
            '''
        user = getattr(request, 'user', None)
        username = user.first_name
        if not username:
            return to_json_data(errno=Code.DBERR, errmsg="上传失败,请先到后台添加正确姓名")
        username1 = user.username
        user1 = Users.objects.only("idcn_id").filter(username=username1).first()
        idcn_id = user1.idcn_id

        if request.method == "POST":

            f1 = request.FILES
            if f1:
                f = f1['my_file']
                type_excel = f.name.split('.')[1]
                if type_excel in ['xls', 'xlsx']:
                    # 开始解析上传的excel表格
                    wb = xlrd.open_workbook(filename=None, file_contents=f.read())  # 关键点在于这里
                    table = wb.sheets()[0]
                    nrows = table.nrows  # 行数
                    # ncole = table.ncols  # 列数
                    try:
                        with transaction.atomic():
                            for i in range(1, nrows):
                                # if 4 == i:
                                #     i/0
                                rowValues = table.row_values(i)  # 一行的数据
                                zb = rowValues[0].strip()
                                jj = rowValues[1].strip()
                                gname = rowValues[3].strip()
                                if zb not in ['5*8时间段工单','非5*8时间段工单']:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 5*8时间段工单或者非5*8时间段工单")
                                if jj not in ['紧急工单', '非紧急工单']:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 紧急工单或者非紧急工单")
                                if type(rowValues[4]) != float:
                                    return to_json_data(errno=Code.DBERR, errmsg="工单量请填写数字")
                                rowValues[4] = int(rowValues[4])
                                dc_content = DesCond.objects.only('btime', 'etime').filter(is_delete=False,fname=rowValues[2]).first()
                                if not dc_content:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 正确的工单类型")
                                dc_id = dc_content.id
                                btime = dc_content.btime
                                etime = int(dc_content.etime)
                                hcount = btime + etime * rowValues[4]
                                if rowValues[2] == "资产盘点":
                                    hcount = hcount * 0.24
                                p_exist = Gd.objects.defer('update_time','create_time').filter(is_delete=False, cuser=username,dc_id=dc_id,gname=gname).first()
                                if p_exist:
                                    p_exist.zb = zb
                                    p_exist.jj = jj
                                    p_exist.gcount = rowValues[4]
                                    p_exist.hcount = hcount
                                    p_exist.idcn_id = idcn_id
                                    p_exist.save()
                                else:
                                    Gd.objects.get_or_create(gname=gname,gcount=rowValues[4],hcount=hcount,cuser=username,dc_id=dc_id,zb=rowValues[0],jj=rowValues[1],idcn_id=idcn_id)

                    except Exception as e:
                        return to_json_data(errno=Code.DBERR, errmsg=error_map[Code.DBERR])

                    return to_json_data()

                return to_json_data(errno=Code.SERVERERR, errmsg=error_map[Code.SERVERERR])

            return to_json_data(errno=Code.NODATA, errmsg=error_map[Code.NODATA])

        return to_json_data(errno=Code.METHERR, errmsg=error_map[Code.METHERR])


class GdtestManageView(LoginRequiredMixin,View):
    """create news manange view
    route:  /admin/gd/
    """
    def get(self, request):
        change_info(request)

        # 2、从前端或取参数
        user = getattr(request, 'user', None)
        username = user.first_name
        if not username:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="查看失败,请先到后台添加正确姓名")
        # newses = Gd.objects.select_related('dc','idcn').order_by('-id').only('id', 'gname', 'gcount', 'hcount', 'update_time','dc_id','idcn_id'). \
        #         filter(is_delete=False,cuser=username)
        newses = Gd.objects.order_by('-id').filter(is_delete=False, cuser=username)


        # 3、通过过滤条件，去数据库中查询
        # 通过时间进行过滤
        # try:
        #     start_time = request.GET.get('start_time', '')
        #     start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''
        #
        #     end_time = request.GET.get('end_time', '')
        #     end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        # except Exception as e:
        #     logger.info("用户输入的时间有误：\n{}".format(e))
        #     start_time = end_time = ''
        #
        # if start_time and not end_time:
        #     newses = newses.filter(update_time__lte=start_time)
        # if end_time and not start_time:
        #     newses = newses.filter(update_time__gte=end_time)
        #
        # if start_time and end_time:
        #     newses = newses.filter(update_time__range=(start_time, end_time))
        #
        # # 通过标签id进行过滤
        # try:
        #     idcn_id = int(request.GET.get('idcn_id', 0))
        # except Exception as e:
        #     logger.info("标签错误：\n{}".format(e))
        #     idcn_id = 0
        # if idcn_id != 0:
        #     newses = newses.filter(is_delete=False, idcn_id=idcn_id)
        #
        # try:
        #     zb_id = int(request.GET.get('zb_id', 0))
        # except Exception as e:
        #     logger.info("时间段错误：\n{}".format(e))
        #     zb_id = 0
        #
        # try:
        #     jj_id = int(request.GET.get('jj_id', 0))
        # except Exception as e:
        #     logger.info("时间段错误：\n{}".format(e))
        #     jj_id = 0
        #
        # if zb_id == 1:
        #     m = "5*8时间段工单"
        #     newses = newses.filter(zb=m)
        # elif zb_id == 2:
        #     m = "非5*8时间段工单"
        #     newses = newses.filter(zb=m)
        #
        # if jj_id == 1:
        #     m1 = "非紧急工单"
        #     newses = newses.filter(jj=m1)
        # elif jj_id == 2:
        #     m1 = "紧急工单"
        #     newses = newses.filter(jj=m1)
        #
        # i = 0
        # for n in newses:
        #     i = i + 1
        #
        # # 获取第几页内容
        # try:
        #     page = int(request.GET.get('page', 1))
        # except Exception as e:
        #     logger.info("当前页数错误：\n{}".format(e))
        #     page = 1
        # paginator = Paginator(newses, constants.PER_PAGE_NEWS_COUNT)
        # try:
        #     news_info = paginator.page(page)
        # except EmptyPage:
        #     # 若用户访问的页数大于实际页数，则返回最后一页数据
        #     logging.info("用户访问的页数大于总页数。")
        #     news_info = paginator.page(paginator.num_pages)
        #
        # paginator_data = paginator_script.get_paginator_data(paginator, news_info)
        #
        # start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        # end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # # 1、获取文章标签
        # idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            # 'number':i,
            'news_info': newses,
            # 'paginator': paginator,
            # 'idcn':idcn,
            # 'start_time': start_time,
            # "end_time": end_time,
            # "idcn_id": idcn_id,
            # "zb_id": zb_id,
            # "jj_id":jj_id,
            # "other_param": urlencode({
            #     "start_time": start_time,
            #     "end_time": end_time,
            #     "idcn_id": idcn_id,
            #     "zb_id": zb_id,
            #     "jj_id":jj_id,
            # })
        }
        # context.update(paginator_data)
        return render(request, 'admin/news/gd_manange_test.html', context=context)



    def post(self,request):
        change_info(request)
        '''
            :param request:
            :return: 上传文件excel表格 ,并进行解析
            '''
        user = getattr(request, 'user', None)
        username = user.first_name
        if not username:
            return to_json_data(errno=Code.DBERR, errmsg="上传失败,请先到后台添加正确姓名")
        username1 = user.username
        user1 = Users.objects.only("idcn_id").filter(username=username1).first()
        idcn_id = user1.idcn_id

        if request.method == "POST":

            f1 = request.FILES
            if f1:
                f = f1['my_file']
                type_excel = f.name.split('.')[1]
                if type_excel in ['xls', 'xlsx']:
                    # 开始解析上传的excel表格
                    wb = xlrd.open_workbook(filename=None, file_contents=f.read())  # 关键点在于这里
                    table = wb.sheets()[0]
                    nrows = table.nrows  # 行数
                    # ncole = table.ncols  # 列数
                    try:
                        with transaction.atomic():
                            for i in range(1, nrows):
                                # if 4 == i:
                                #     i/0
                                rowValues = table.row_values(i)  # 一行的数据
                                zb = rowValues[0].strip()
                                jj = rowValues[1].strip()
                                gname = rowValues[3].strip()
                                if zb not in ['5*8时间段工单','非5*8时间段工单']:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 5*8时间段工单或者非5*8时间段工单")
                                if jj not in ['紧急工单', '非紧急工单']:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 紧急工单或者非紧急工单")
                                if type(rowValues[4]) != float:
                                    return to_json_data(errno=Code.DBERR, errmsg="工单量请填写数字")
                                rowValues[4] = int(rowValues[4])
                                dc_content = DesCond.objects.only('btime', 'etime').filter(is_delete=False,fname=rowValues[2]).first()
                                if not dc_content:
                                    return to_json_data(errno=Code.DBERR, errmsg="请填写 正确的工单类型")
                                dc_id = dc_content.id
                                btime = dc_content.btime
                                etime = int(dc_content.etime)
                                hcount = btime + etime * rowValues[4]
                                if rowValues[2] == "资产盘点":
                                    hcount = hcount * 0.24
                                p_exist = Gd.objects.defer('update_time','create_time').filter(is_delete=False, cuser=username,dc_id=dc_id,gname=gname).first()
                                if p_exist:
                                    p_exist.zb = zb
                                    p_exist.jj = jj
                                    p_exist.gcount = rowValues[4]
                                    p_exist.hcount = hcount
                                    p_exist.idcn_id = idcn_id
                                    p_exist.save()
                                else:
                                    Gd.objects.get_or_create(gname=gname,gcount=rowValues[4],hcount=hcount,cuser=username,dc_id=dc_id,zb=rowValues[0],jj=rowValues[1],idcn_id=idcn_id)

                    except Exception as e:
                        return to_json_data(errno=Code.DBERR, errmsg=error_map[Code.DBERR])

                    return to_json_data()

                return to_json_data(errno=Code.SERVERERR, errmsg=error_map[Code.SERVERERR])

            return to_json_data(errno=Code.NODATA, errmsg=error_map[Code.NODATA])

        return to_json_data(errno=Code.METHERR, errmsg=error_map[Code.METHERR])



class GdmbDownLoad(LoginRequiredMixin,View):
    """"
    download template of moves
    """
    def get(self,request):
        change_info(request)
        ws = Workbook(encoding='utf-8')
        w = ws.add_sheet(u"sheet1")
        w.write(0, 0, "工单时间段")
        w.write(0, 1, "紧急程度")
        w.write(0, 2, "工单类型")
        w.write(0, 3, "工单链接")
        w.write(0, 4, "工单量")
        w.write(1, 0, "必须填写正确的工单时间段")
        w.write(1, 1, "必须填写正确的紧急程度")
        w.write(1, 2, "必须填写正确的工单类型")
        w.write(1, 3, "无要求")
        w.write(1, 4, "工单量必须为整数")


        sio = BytesIO()  # 这里原博客是StringIO.StringIO()，发现有点问题
        ws.save(sio)
        sio.seek(0)
        # final_filename = '建德内部资产.xls'
        # doc_filename = escape_uri_path(final_filename)
        response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename=template.xls'
        response.write(sio.getvalue())
        return response

class JfgdManageView(LoginRequiredMixin,View):
    """create news manange view
    route:  /admin/gd/
    """
    def get(self, request):
        change_info(request)

        # 2、从前端或取参数
        user = getattr(request, 'user', None)
        idcn_id = user.idcn_id
        if not idcn_id:
            return to_json_data(errno=Code.UNKOWNERR, errmsg="查看失败,请先到后台添加正确机房")
        newses = Gd.objects.select_related('dc','idcn').order_by('-id').only('id', 'gname', 'gcount', 'hcount', 'update_time','dc_id','idcn_id'). \
                filter(is_delete=False,idcn_id=idcn_id)


        # 3、通过过滤条件，去数据库中查询
        # 通过时间进行过滤
        try:
            start_time = request.GET.get('start_time', '')
            start_time = datetime.strptime(start_time, '%Y/%m/%d') if start_time else ''

            end_time = request.GET.get('end_time', '')
            end_time = datetime.strptime(end_time, '%Y/%m/%d') if end_time else ''
        except Exception as e:
            logger.info("用户输入的时间有误：\n{}".format(e))
            start_time = end_time = ''

        if start_time and not end_time:
            newses = newses.filter(update_time__lte=start_time)
        if end_time and not start_time:
            newses = newses.filter(update_time__gte=end_time)

        if start_time and end_time:
            end1_time = (end_time + timedelta(days=+1)).strftime("%Y/%m/%d")
            end1_time = datetime.strptime(end1_time, '%Y/%m/%d')
            newses = newses.filter(update_time__range=(start_time, end1_time))

        # 通过标签id进行过滤
        try:
            idcn_id = int(request.GET.get('idcn_id', 0))
        except Exception as e:
            logger.info("标签错误：\n{}".format(e))
            idcn_id = 0
        if idcn_id != 0:
            newses = newses.filter(is_delete=False, idcn_id=idcn_id)

        try:
            zb_id = int(request.GET.get('zb_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            zb_id = 0

        try:
            jj_id = int(request.GET.get('jj_id', 0))
        except Exception as e:
            logger.info("时间段错误：\n{}".format(e))
            jj_id = 0

        if zb_id == 1:
            m = "5*8时间段工单"
            newses = newses.filter(zb=m)
        elif zb_id == 2:
            m = "非5*8时间段工单"
            newses = newses.filter(zb=m)

        if jj_id == 1:
            m1 = "非紧急工单"
            newses = newses.filter(jj=m1)
        elif jj_id == 2:
            m1 = "紧急工单"
            newses = newses.filter(jj=m1)

        i = 0
        for n in newses:
            i = i + 1

        # 获取第几页内容
        try:
            page = int(request.GET.get('page', 1))
        except Exception as e:
            logger.info("当前页数错误：\n{}".format(e))
            page = 1
        paginator = Paginator(newses, constants.PER_PAGE_NEWS_COUNT)
        try:
            news_info = paginator.page(page)
        except EmptyPage:
            # 若用户访问的页数大于实际页数，则返回最后一页数据
            logging.info("用户访问的页数大于总页数。")
            news_info = paginator.page(paginator.num_pages)

        paginator_data = paginator_script.get_paginator_data(paginator, news_info)

        start_time = start_time.strftime('%Y/%m/%d') if start_time else ''
        end_time = end_time.strftime('%Y/%m/%d') if end_time else ''
        # 1、获取文章标签
        idcn = IdcN.objects.only('id', 'name').filter(is_delete=False)
        context = {
            'number':i,
            'news_info': news_info,
            'paginator': paginator,
            'idcn':idcn,
            'start_time': start_time,
            "end_time": end_time,
            "idcn_id": idcn_id,
            "zb_id": zb_id,
            "jj_id":jj_id,
            "other_param": urlencode({
                "start_time": start_time,
                "end_time": end_time,
                "idcn_id": idcn_id,
                "zb_id": zb_id,
                "jj_id":jj_id,
            })
        }
        context.update(paginator_data)
        return render(request, 'admin/news/jfgd_manange.html', context=context)

class UpdateIndex(LoginRequiredMixin,View):
    """
    test execl upload to mysql
    """
#     permission_required = ('change_idcp')
#     raise_exception = True


    def get(self,request):
        change_info(request)
        return render(request, 'admin/index/update.html')

    @method_decorator(my_decorator)
    def post(self,request):
        change_info(request)
        '''
            :param request:
            :return: 上传文件excel表格 ,并进行解析
            '''
        if request.method == "POST":

            f1 = request.FILES
            if f1:
                f = f1['my_file']
                type_excel = f.name.split('.')[1]
                if type_excel in ['xls', 'xlsx']:
                    # 开始解析上传的excel表格
                    wb = xlrd.open_workbook(filename=None, file_contents=f.read())  # 关键点在于这里
                    table = wb.sheets()[0]
                    nrows = table.nrows  # 行数
                    # ncole = table.ncols  # 列数
                    try:
                        with transaction.atomic():
                            for i in range(1, nrows):
                                # if 4 == i:
                                #     i/0
                                rowValues = table.row_values(i)  # 一行的数据
                                p_exist = DesCond.objects.defer('update_time','create_time').filter(is_delete=False, fname=rowValues[0]).first()
                                if p_exist:
                                    p_exist.cunit = rowValues[1]
                                    p_exist.btime = rowValues[2]
                                    p_exist.etime = rowValues[3]
                                    p_exist.save()
                                else:
                                    DesCond.objects.get_or_create(fname=rowValues[0], cunit=rowValues[1],btime=rowValues[2],etime=rowValues[3])

                    except Exception as e:
                        return to_json_data(errno=Code.DBERR, errmsg=error_map[Code.DBERR])

                    return to_json_data()

                return to_json_data(errno=Code.SERVERERR, errmsg=error_map[Code.SERVERERR])

            return to_json_data(errno=Code.NODATA, errmsg=error_map[Code.NODATA])

        return to_json_data(errno=Code.METHERR, errmsg=error_map[Code.METHERR])



class NewsEditView(PermissionRequiredMixin, View):
    """
    """
    permission_required = ('news.change_news', 'news.delete_news')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(NewsEditView, self).handle_no_permission()

    def get(self, request, news_id):
        change_info(request)
        """
        获取待编辑的工单记录
        """
        news = Gd.objects.select_related('dc','idcn').only('dc__fname','idcn__name','dc__cunit').filter(is_delete=False, id=news_id).first()
        if news:
            dcs = DesCond.objects.only('id', 'fname').filter(is_delete=False)
            idcns = IdcN.objects.only('id','name').filter(is_delete=False)
            context = {
                'dcs': dcs,
                'idcns':idcns,
                'news': news,
            }
            return render(request, 'gdsc/gdbj.html', context=context)
        else:
            raise Http404('需要更新的工单记录不存在！')

    def delete(self, request, news_id):
        change_info(request)
        """
        删除工单记录
        """
        news = Gd.objects.only('id').filter(id=news_id).first()
        if news:
            news.is_delete = True
            news.save(update_fields=['is_delete'])
            return to_json_data(errmsg="工单记录删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的工单记录不存在")

    def put(self, request, news_id):
        change_info(request)
        """
        更新工单记录
        """
        news = Gd.objects.filter(is_delete=False, id=news_id).first()
        if not news:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的工单记录不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        gdtime = dict_data["sGdtime"]
        gdjj = dict_data["sGdjj"]
        gdLink = dict_data["sGdLink"]
        gdtype = dict_data["sGdType"].split('|')[0]
        gdnumber = int(dict_data["sGdNumber"])
        dc_content = DesCond.objects.only('btime', 'etime').filter(is_delete=False, fname=gdtype).first()
        dc_id = dc_content.id
        btime = int(dc_content.btime)
        etime = int(dc_content.etime)
        hcount = btime + etime * gdnumber
        if gdtype == "资产盘点":
            hcount = hcount*0.24
        news.gname = gdLink
        news.gcount = gdnumber
        news.hcount = hcount
        news.dc_id = dc_id
        news.zb = gdtime
        news.jj = gdjj
        news.save(update_fields=['gname','gcount','hcount','dc_id','zb','jj'])
        return to_json_data(errmsg='工单记录更新成功')


class GdEditView(LoginRequiredMixin, View):
    """
    """


    def get(self, request, news_id):
        change_info(request)
        """
        获取待编辑的工单记录
        """
        news = Gd.objects.select_related('dc','idcn').only('dc__fname','idcn__name','dc__cunit').filter(is_delete=False, id=news_id).first()
        if news:
            dcs = DesCond.objects.only('id', 'fname').filter(is_delete=False)
            idcns = IdcN.objects.only('id','name').filter(is_delete=False)
            context = {
                'dcs': dcs,
                'idcns':idcns,
                'news': news,
            }
            return render(request, 'gdsc/gdbj.html', context=context)
        else:
            raise Http404('需要更新的工单记录不存在！')

    def delete(self, request, news_id):
        change_info(request)
        """
        删除工单记录
        """
        news = Gd.objects.only('id').filter(id=news_id).first()
        if news:
            news.is_delete = True
            news.save(update_fields=['is_delete'])
            return to_json_data(errmsg="工单记录删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的工单记录不存在")

    def put(self, request, news_id):
        change_info(request)
        """
        更新工单记录
        """
        news = Gd.objects.filter(is_delete=False, id=news_id).first()
        if not news:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的工单记录不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        gdtime = dict_data["sGdtime"]
        gdjj = dict_data["sGdjj"]
        gdLink = dict_data["sGdLink"].strip()
        gdtype = dict_data["sGdType"].split('|')[0]
        gdnumber = int(dict_data["sGdNumber"])
        dc_content = DesCond.objects.only('btime', 'etime').filter(is_delete=False, fname=gdtype).first()
        dc_id = dc_content.id
        btime = int(dc_content.btime)
        etime = int(dc_content.etime)
        hcount = btime + etime * gdnumber
        if gdtype == "资产盘点":
            hcount = hcount * 0.24
        news.gname = gdLink
        news.gcount = gdnumber
        news.hcount = hcount
        news.dc_id = dc_id
        news.zb = gdtime
        news.jj = gdjj
        news.save(update_fields=['gname', 'gcount', 'hcount', 'dc_id', 'zb','jj'])
        return to_json_data(errmsg='工单记录更新成功')

class NewsPubView(PermissionRequiredMixin, View):
# class NewsPubView(View):
    """public news view
    route: /admin/news/pub/
    """
    permission_required = ('news.add_news', 'news.view_news')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(NewsPubView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        """
        获取文章标签
        """
        tags = models.Tag.objects.only('id', 'name').filter(is_delete=False)

        return render(request, 'admin/news/news_pub.html', locals())

    def post(self, request):
        change_info(request)
        # 1、从前端获取参数
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        # 2、校验
        form = forms.NewsPubForm(data=dict_data)
        if form.is_valid():
            # 3、保存到数据库
            # n = models.News(**form.cleaned_data)
            # n.title = form.cleaned_data.get('title')
            #
            # n.save()
            news_instance = form.save(commit=False)
            news_instance.author = request.user
            # news_instance.author_id = 1     # for test
            news_instance.save()
            # 4、返回执行结果
            return to_json_data(errmsg='文章创建成功')
        else:
            # 定义一个错误信息列表
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)


class NewsUploadImage(PermissionRequiredMixin, View):
    """
    """
    permission_required = ('news.add_news', )

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有上传图片的权限')

    def post(self, request):
        change_info(request)
        image_file = request.FILES.get('image_file')
        if not image_file:
            logger.info('从前端获取图片失败')
            return to_json_data(errno=Code.NODATA, errmsg='从前端获取图片失败')

        if image_file.content_type not in ('image/jpeg', 'image/png', 'image/gif'):
            return to_json_data(errno=Code.DATAERR, errmsg='不能上传非图片文件')

        try:
            # click_object_store.jpg
            image_ext_name = image_file.name.split('.')[-1]
        except Exception as e:
            logger.info('图片拓展名异常：{}'.format(e))
            image_ext_name = 'jpg'

        try:
            upload_res = FDFS_Client.upload_by_buffer(image_file.read(), file_ext_name=image_ext_name)
        except Exception as e:
            logger.error('图片上传出现异常：{}'.format(e))
            return to_json_data(errno=Code.UNKOWNERR, errmsg='图片上传异常')
        else:
            if upload_res.get('Status') != 'Upload successed.':
                logger.info('图片上传到FastDFS服务器失败')
                return to_json_data(Code.UNKOWNERR, errmsg='图片上传到服务器失败')
            else:
                image_name = upload_res.get('Remote file_id')
                image_url = settings.FASTDFS_SERVER_DOMAIN + image_name
                image_list = models.Images()
                image_list.image_url = image_url
                image_list.save()
                return to_json_data(data={'image_url': image_url}, errmsg='图片上传成功')

class ImagesShow(View):
    def get(self,request):
        images_query = models.Images.objects.filter(is_delete=False)
        return render(request,'images.html',locals())


class UploadToken(PermissionRequiredMixin, View):
    """
    """
    permission_required = ('news.add_news', 'news.view_news',)

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有权限')

    def get(self, request):
        change_info(request)
        access_key = qiniu_secret_info.QI_NIU_ACCESS_KEY
        secret_key = qiniu_secret_info.QI_NIU_SECRET_KEY
        bucket_name = qiniu_secret_info.QI_NIU_BUCKET_NAME
        # 构建鉴权对象
        q = qiniu.Auth(access_key, secret_key)
        token = q.upload_token(bucket_name)

        return JsonResponse({"uptoken": token})

# IndexView = my_decorator(IndexView)
# get = my_decorator(get)

# @login_required(login_url='users:login')
# @permission_required('news.delete_news', raise_exception=True)
# class index(PermissionRequiredMixin, View):
#     def get(self,request):
#
#         return render(request, 'admin/index/index.html', locals())


class TagsManageView(PermissionRequiredMixin, View):
    """create tags manage view
    route: /admin/tags/
    """
    permission_required = ('news.add_tag', 'news.view_tag')
    raise_exception = True

    # def get_permission_required(self):
    #     content_type = ContentType.objects.get_for_model(models.Tag)
    #     permissions = Permission.objects.filter(content_type=content_type)
    #     pass

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(TagsManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        # tags = models.IdcN.objects.values('id', 'name').annotate(num_news=Count('idcp')).filter(is_delete=False).\
        #     order_by('-num_news', '-update_time')
        idcn = IdcN.objects.values('id', 'name').filter(is_delete=False)

        return render(request, 'admin/news/tags_manage.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name')
        if tag_name:
            tag_name = tag_name.strip()
            tag_tuple = IdcN.objects.get_or_create(name=tag_name)
            tag_instance, tag_created_bolean = tag_tuple
            new_tag_dict = {
                "id": tag_instance.id,
                "name": tag_instance.name
            }
            if tag_created_bolean:
                return to_json_data(errmsg="标签创建成功", data=new_tag_dict)
            else:
                if tag_instance.is_delete:
                    tag_instance.is_delete = False
                    tag_instance.save()
                    return to_json_data(errmsg="标签创建成功")
                else:
                    return to_json_data(errno=Code.DATAEXIST, errmsg="标签名已存在")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="标签名为空")


class TagEditView(PermissionRequiredMixin, View):
    """create tags name view
    route: /admin/tags/<int:tag_id>/
    """
    permission_required = ('news.change_tag', 'news.delete_tag')
    raise_exception = True

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')

    def delete(self, request, tag_id):
        change_info(request)
        Idcn = IdcN.objects.only('id').filter(is_delete=False, id=tag_id).first()
        if Idcn:
            # tag.delete()
            Idcn.is_delete = True
            Idcn.save(update_fields=['is_delete'])
            return to_json_data(errmsg="机房名称删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的标签不存在")

    def put(self, request, tag_id):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name')

        tag = IdcN.objects.only('id').filter(id=tag_id).first()
        tag1 = IdcN.objects.only('id').filter(name=tag_name).first()
        if tag:
            if tag_name and tag_name.strip():
                if not IdcN.objects.only('id').filter(name=tag_name).exists():
                    tag.name = tag_name
                    tag.save(update_fields=['name'])
                    return to_json_data(errmsg='标签更新成功')
                else:
                    if tag1.is_delete:
                        tag1.is_delete = False
                        tag1.save(update_fields=['is_delete'])
                        tag.is_delete = True
                        tag.save(update_fields=['is_delete'])
                        return to_json_data(errmsg='标签更新成功')
                    else:
                        return to_json_data(errno=Code.PARAMERR, errmsg='标签名已存在')
            else:
                return to_json_data(errno=Code.PARAMERR, errmsg='标签名不能空')
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg='需要更新的标签不存在')


class ModManageView(PermissionRequiredMixin, View):
    """create tags manage view
    route: /admin/tags/
    """
    permission_required = ('news.add_tag', 'news.view_tag')
    raise_exception = True

    # def get_permission_required(self):
    #     content_type = ContentType.objects.get_for_model(models.Tag)
    #     permissions = Permission.objects.filter(content_type=content_type)
    #     pass

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(ModManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        # tags = models.IdcN.objects.values('id', 'name').annotate(num_news=Count('idcp')).filter(is_delete=False).\
        #     order_by('-num_news', '-update_time')
        idcr = IdcR.objects.select_related('R').only('id', 'rname','R__name').filter(is_delete=False)


        return render(request, 'admin/news/mods_manage.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name').split('/')[0]
        idcr_str = dict_data.get('name').split('/')[1]
        idcr = IdcN.objects.only('id','name').filter(is_delete=False)
        idcr_id = ""
        for _ in idcr:
            if idcr_str == _.name:
                idcr_id = _.id
        if idcr_id == "":
            return to_json_data(errno=Code.PARAMERR, errmsg="机房标签名不存在")
        if tag_name:
            tag_name = tag_name.strip()
            tag_tuple = IdcR.objects.get_or_create(rname=tag_name,R_id=idcr_id)
            tag_instance, tag_created_bolean = tag_tuple
            new_tag_dict = {
                "id": tag_instance.id,
                "name": tag_instance.rname
            }
            if tag_created_bolean:
                return to_json_data(errmsg="标签创建成功", data=new_tag_dict)
            else:
                if tag_instance.is_delete:
                    tag_instance.is_delete = False
                    tag_instance.save()
                    return to_json_data(errmsg="标签创建成功")
                else:
                    return to_json_data(errno=Code.DATAEXIST, errmsg="标签名已存在")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="标签名为空")


class ModEditView(PermissionRequiredMixin, View):
    """create tags name view
    route: /admin/tags/<int:tag_id>/
    """
    permission_required = ('news.change_tag', 'news.delete_tag')
    raise_exception = True

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')

    def delete(self, request, mod_id):
        change_info(request)
        Idcn = IdcR.objects.only('id').filter(is_delete=False, id=mod_id).first()
        if Idcn:
            # tag.delete()
            Idcn.is_delete = True
            Idcn.save(update_fields=['is_delete'])
            return to_json_data(errmsg="机房名称删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的标签不存在")

    def put(self, request, mod_id):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name').split('/')[0]
        idcr_str = dict_data.get('name').split('/')[1]
        idcr = IdcN.objects.only('id', 'name').filter(is_delete=False)
        idcr_id = ""
        for _ in idcr:
            if idcr_str == _.name:
                idcr_id = _.id
        if idcr_id == "":
            return to_json_data(errno=Code.PARAMERR, errmsg="机房标签名不存在")

        tag = IdcR.objects.only('id').filter(id=mod_id).first()
        tag1 = IdcR.objects.only('id').filter(rname=tag_name,R_id=idcr_id).first()
        if tag:
            if tag_name and tag_name.strip():
                if not IdcR.objects.only('id').filter(rname=tag_name,R_id=idcr_id).exists():
                    tag.rname = tag_name
                    tag.R_id = idcr_id
                    tag.save(update_fields=['rname','R_id'])
                    return to_json_data(errmsg='标签更新成功')
                else:
                    if tag1.is_delete:
                        tag1.is_delete = False
                        tag1.save(update_fields=['is_delete'])
                        tag.is_delete = True
                        tag.save(update_fields=['is_delete'])
                        return to_json_data(errmsg='标签更新成功')
                    else:
                        return to_json_data(errno=Code.PARAMERR, errmsg='标签名已存在')
            else:
                return to_json_data(errno=Code.PARAMERR, errmsg='标签名不能空')
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg='需要更新的标签不存在')



class SupplierManageView(PermissionRequiredMixin, View):
    """create tags manage view
    route: /admin/tags/
    """
    permission_required = ('news.add_tag', 'news.view_tag')
    raise_exception = True

    # def get_permission_required(self):
    #     content_type = ContentType.objects.get_for_model(models.Tag)
    #     permissions = Permission.objects.filter(content_type=content_type)
    #     pass

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(SupplierManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        # tags = models.IdcN.objects.values('id', 'name').annotate(num_news=Count('idcp')).filter(is_delete=False).\
        #     order_by('-num_news', '-update_time')
        supplier = Supplier.objects.values('id', 'sname').filter(is_delete=False)

        return render(request, 'admin/news/supplier_manage.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name')
        if tag_name:
            tag_name = tag_name.strip()
            tag_tuple = Supplier.objects.get_or_create(sname=tag_name)
            tag_instance, tag_created_bolean = tag_tuple
            new_tag_dict = {
                "id": tag_instance.id,
                "name": tag_instance.sname
            }
            if tag_created_bolean:
                return to_json_data(errmsg="标签创建成功", data=new_tag_dict)
            else:
                if tag_instance.is_delete:
                    tag_instance.is_delete = False
                    tag_instance.save()
                    return to_json_data(errmsg="标签创建成功")
                else:
                    return to_json_data(errno=Code.DATAEXIST, errmsg="标签名已存在")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="标签名为空")


class SupplierEditView(PermissionRequiredMixin, View):
    """create tags name view
    route: /admin/tags/<int:tag_id>/
    """
    permission_required = ('news.change_tag', 'news.delete_tag')
    raise_exception = True

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')

    def delete(self, request, sup_id):
        change_info(request)
        Idcn = Supplier.objects.only('id').filter(is_delete=False, id=sup_id).first()
        if Idcn:
            # tag.delete()
            Idcn.is_delete = True
            Idcn.save(update_fields=['is_delete'])
            return to_json_data(errmsg="机房名称删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的标签不存在")

    def put(self, request, sup_id):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))
        tag_name = dict_data.get('name')

        tag = Supplier.objects.only('id').filter(id=sup_id).first()
        tag1 = Supplier.objects.only('id').filter(sname=tag_name).first()
        if tag:
            if tag_name and tag_name.strip():
                if not Supplier.objects.only('id').filter(sname=tag_name).exists():
                    tag.sname = tag_name
                    tag.save(update_fields=['sname'])
                    return to_json_data(errmsg='标签更新成功')
                else:
                    if tag1.is_delete:
                        tag1.is_delete = False
                        tag1.save(update_fields=['is_delete'])
                        tag.is_delete = True
                        tag.save(update_fields=['is_delete'])
                        return to_json_data(errmsg='标签更新成功')
                    else:
                        return to_json_data(errno=Code.PARAMERR, errmsg='标签名已存在')
            else:
                return to_json_data(errno=Code.PARAMERR, errmsg='标签名不能空')
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg='需要更新的标签不存在')


# class Test(PermissionRequiredMixin, View):
#     """
#
#     """
#     permission_required = ('news.change_tag', 'news.delete_tag')
#     raise_exception = True
#
#     def handle_no_permission(self):
#         #
#         return to_json_data()
#
#     def get(self, reqeust):
#         return to_json_data()

class HotNewsManageView(PermissionRequiredMixin, View):
    """
    """
    permission_required = ('news.view_hotnews', )
    raise_exception = True

    def get(self, request):
        change_info(request)
        hot_news = models.HotNews.objects.select_related('news__tag'). \
                       only('news_id', 'news__title', 'news__tag__name', 'priority'). \
                       filter(is_delete=False).order_by('priority', '-news__clicks')[0:SHOW_HOTNEWS_COUNT]

        return render(request, 'admin/news/news_hot.html', locals())


class HotNewsEditView(PermissionRequiredMixin, View):
    """
    """
    permission_required = ('news.change_hotnews', 'news.delete_hotnews')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(HotNewsEditView, self).handle_no_permission()

    def delete(self, request, hotnews_id):
        change_info(request)
        hotnews = models.HotNews.objects.only('id').filter(id=hotnews_id).first()
        if hotnews:
            hotnews.is_delete = True
            hotnews.save(update_fields=['is_delete'])
            return to_json_data(errmsg="热门文章删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的热门文章不存在")

    def put(self, request, hotnews_id):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        try:
            priority = int(dict_data.get('priority'))
            priority_list = [i for i, _ in models.HotNews.PRI_CHOICES]
            if priority not in priority_list:
                return to_json_data(errno=Code.PARAMERR, errmsg='热门文章的优先级设置错误')
        except Exception as e:
            logger.info('热门文章优先级异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='热门文章的优先级设置错误')

        hotnews = models.HotNews.objects.only('id').filter(id=hotnews_id).first()
        if not hotnews:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要更新的热门文章不存在")

        if hotnews.priority == priority:
            return to_json_data(errno=Code.PARAMERR, errmsg="热门文章的优先级未改变")

        hotnews.priority = priority
        hotnews.save(update_fields=['priority'])
        return to_json_data(errmsg="热门文章更新成功")


class HotNewsAddView(PermissionRequiredMixin, View):
    """
    route: /admin/hotnews/add/
    """
    permission_required = ('news.add_hotnews', 'news.view_hotnews')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(HotNewsAddView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        tags = models.Tag.objects.values('id', 'name').annotate(num_news=Count('news')). \
            filter(is_delete=False).order_by('-num_news', 'update_time')
        # 优先级列表
        # priority_list = {K: v for k, v in models.HotNews.PRI_CHOICES}
        priority_dict = OrderedDict(models.HotNews.PRI_CHOICES)

        return render(request, 'admin/news/news_hot_add.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        try:
            news_id = int(dict_data.get('news_id'))
        except Exception as e:
            logger.info('前端传过来的文章id参数异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='参数错误')

        if not models.News.objects.filter(id=news_id).exists():
            return to_json_data(errno=Code.PARAMERR, errmsg='文章不存在')

        try:
            priority = int(dict_data.get('priority'))
            priority_list = [i for i, _ in models.HotNews.PRI_CHOICES]
            if priority not in priority_list:
                return to_json_data(errno=Code.PARAMERR, errmsg='热门文章的优先级设置错误')
        except Exception as e:
            logger.info('热门文章优先级异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='热门文章的优先级设置错误')

        # 创建热门新闻
        hotnews_tuple = models.HotNews.objects.get_or_create(news_id=news_id)
        hotnews, is_created = hotnews_tuple
        hotnews.priority = priority  # 修改优先级
        hotnews.is_delete = False
        hotnews.save(update_fields=['priority','is_delete'])
        return to_json_data(errmsg="热门文章创建成功")


class NewsByTagIdView(PermissionRequiredMixin, View):
    """
    route: /admin/tags/<int:tag_id>/news/
    """
    permission_required = ('news.view_news', 'news.add_hotnews')
    # raise_exception = True

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')

    def get(self, request, tag_id):
        change_info(request)
        newses = models.News.objects.values('id', 'title').filter(is_delete=False, tag_id=tag_id)
        news_list = [i for i in newses]

        return to_json_data(data={
            'news': news_list
        })


class BannerManageView(PermissionRequiredMixin, View):
    permission_required = ('news.view_banner', )
    raise_exception = True

    def get(self, request):
        change_info(request)
        priority_dict = OrderedDict(models.Banner.PRI_CHOICES)
        banners = models.Banner.objects.only('image_url', 'priority').filter(is_delete=False)
        return render(request, 'admin/news/news_banner.html', locals())


class BannerEditView(PermissionRequiredMixin, View):
    permission_required = ('news.delete_banner', 'news.change_banner')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(BannerEditView, self).handle_no_permission()

    def delete(self, request, banner_id):
        change_info(request)
        banner = models.Banner.objects.only('id').filter(id=banner_id).first()
        if banner:
            banner.is_delete = True
            banner.save(update_fields=['is_delete'])
            return to_json_data(errmsg="轮播图删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的轮播图不存在")

    def put(self, request, banner_id):
        change_info(request)
        banner = models.Banner.objects.only('id').filter(id=banner_id).first()
        if not banner:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要更新的轮播图不存在")

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        try:
            priority = int(dict_data.get('priority'))
            priority_list = [i for i, _ in models.Banner.PRI_CHOICES]
            if priority not in priority_list:
                return to_json_data(errno=Code.PARAMERR, errmsg='轮播图的优先级设置错误')
        except Exception as e:
            logger.info('轮播图优先级异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='轮播图的优先级设置错误')

        image_url = dict_data.get('image_url')
        if not image_url:
            return to_json_data(errno=Code.PARAMERR, errmsg='轮播图url为空')

        if banner.priority == priority and banner.image_url == image_url:
            return to_json_data(errno=Code.PARAMERR, errmsg="轮播图的参数未改变")

        banner.priority = priority
        banner.image_url = image_url
        banner.save(update_fields=['priority', 'image_url'])
        return to_json_data(errmsg="轮播图更新成功")


class BannerAddView(PermissionRequiredMixin, View):
    permission_required = ('news.delete_banner', 'news.change_banner', 'news.view_banner')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(BannerAddView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        tags = models.Tag.objects.values('id', 'name').annotate(num_news=Count('news')). \
            filter(is_delete=False).order_by('-num_news', 'update_time')
        # 优先级列表
        # priority_list = {K: v for k, v in models.Banner.PRI_CHOICES}
        priority_dict = OrderedDict(models.Banner.PRI_CHOICES)

        return render(request, 'admin/news/news_banner_add.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        try:
            news_id = int(dict_data.get('news_id'))
        except Exception as e:
            logger.info('前端传过来的文章id参数异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='参数错误')

        if not models.News.objects.filter(id=news_id).exists():
            return to_json_data(errno=Code.PARAMERR, errmsg='文章不存在')

        try:
            priority = int(dict_data.get('priority'))
            priority_list = [i for i, _ in models.Banner.PRI_CHOICES]
            if priority not in priority_list:
                return to_json_data(errno=Code.PARAMERR, errmsg='轮播图的优先级设置错误')
        except Exception as e:
            logger.info('轮播图优先级异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='轮播图的优先级设置错误')

        # 获取轮播图url
        image_url = dict_data.get('image_url')
        if not image_url:
            return to_json_data(errno=Code.PARAMERR, errmsg='轮播图url为空')

        # 创建轮播图
        banners_tuple = models.Banner.objects.get_or_create(news_id=news_id)
        banner, is_created = banners_tuple

        banner.priority = priority
        banner.image_url = image_url
        banner.save(update_fields=['priority', 'image_url'])
        return to_json_data(errmsg="轮播图创建成功")


class DocsManageView(PermissionRequiredMixin, View):
    """
    route: /admin/docs/
    """
    permission_required = ('doc.view_doc', 'doc.add_doc')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(DocsManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        docs = Doc.objects.only('title', 'create_time').filter(is_delete=False)
        return render(request, 'admin/doc/docs_manage.html', locals())


class DocsEditView(PermissionRequiredMixin, View):
    """
    route: /admin/docs/<int:doc_id>/
    """
    permission_required = ('doc.change_doc', 'doc.delete_doc')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(DocsEditView, self).handle_no_permission()

    def get(self, request, doc_id):
        change_info(request)
        """
        """
        doc = Doc.objects.filter(is_delete=False, id=doc_id).first()
        if doc:
            tags = Doc.objects.only('id', 'name').filter(is_delete=False)
            context = {
                'doc': doc
            }
            return render(request, 'admin/doc/docs_pub.html', context=context)
        else:
            raise Http404('需要更新的文章不存在！')

    def delete(self, request, doc_id):
        change_info(request)
        doc = Doc.objects.filter(is_delete=False, id=doc_id).first()
        if doc:
            doc.is_delete = True
            doc.save(update_fields=['is_delete'])
            return to_json_data(errmsg="文档删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的文档不存在")

    def put(self, request, doc_id):
        change_info(request)
        doc = Doc.objects.filter(is_delete=False, id=doc_id).first()
        if not doc:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的文档不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        form = forms.DocsPubForm(data=dict_data)
        if form.is_valid():
            doc.title = form.cleaned_data.get('title')
            doc.desc = form.cleaned_data.get('desc')
            doc.file_url = form.cleaned_data.get('file_url')
            doc.image_url = form.cleaned_data.get('image_url')
            doc.save()
            return to_json_data(errmsg='文档更新成功')
        else:
            # 定义一个错误信息列表
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)


class DocsPubView(PermissionRequiredMixin, View):
    """
    route: /admin/news/pub/
    """
    permission_required = ('doc.add_doc', 'doc.view_doc')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(DocsPubView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        return render(request, 'admin/doc/docs_pub.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        form = forms.DocsPubForm(data=dict_data)
        if form.is_valid():
            docs_instance = form.save(commit=False)
            docs_instance.author_id = request.user.id
            docs_instance.save()
            return to_json_data(errmsg='文档创建成功')
        else:
            # 定义一个错误信息列表
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)


class DocsUploadFile(PermissionRequiredMixin, View):
    """route: /admin/docs/files/
    """
    permission_required = ('doc.add_doc', )

    def handle_no_permission(self):
        return to_json_data(errno=Code.ROLEERR, errmsg='没有上传文件的权限')

    def post(self, request):
        change_info(request)
        text_file = request.FILES.get('text_file')
        if not text_file:
            logger.info('从前端获取文件失败')
            return to_json_data(errno=Code.NODATA, errmsg='从前端获取文件失败')

        if text_file.content_type not in ('application/msword', 'application/octet-stream', 'application/pdf',
                                          'application/zip', 'text/plain', 'application/x-rar'):
            return to_json_data(errno=Code.DATAERR, errmsg='不能上传非文本文件')

        try:
            text_ext_name = text_file.name.split('.')[-1]
        except Exception as e:
            logger.info('文件拓展名异常：{}'.format(e))
            text_ext_name = 'pdf'

        try:
            upload_res = FDFS_Client.upload_by_buffer(text_file.read(), file_ext_name=text_ext_name)
        except Exception as e:
            logger.error('文件上传出现异常：{}'.format(e))
            return to_json_data(errno=Code.UNKOWNERR, errmsg='文件上传异常')
        else:
            if upload_res.get('Status') != 'Upload successed.':
                logger.info('文件上传到FastDFS服务器失败')
                return to_json_data(Code.UNKOWNERR, errmsg='文件上传到服务器失败')
            else:
                text_name = upload_res.get('Remote file_id')
                text_url = settings.FASTDFS_SERVER_DOMAIN + text_name
                return to_json_data(data={'text_file': text_url}, errmsg='文件上传成功')


class CoursesManageView(PermissionRequiredMixin, View):
    """
    route: /admin/courses/
    """
    permission_required = ('course.add_course', 'course.view_course')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(CoursesManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        courses = Course.objects.select_related('category', 'teacher').\
            only('title', 'category__name', 'teacher__name').filter(is_delete=False)
        return render(request, 'admin/course/courses_manage.html', locals())


class CoursesEditView(PermissionRequiredMixin, View):
    """
    route: /admin/courses/<int:course_id>/
    """
    permission_required = ('course.change_course', 'course.delete_course')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(CoursesEditView, self).handle_no_permission()

    def get(self, request, course_id):
        change_info(request)
        """
        """
        course = Course.objects.filter(is_delete=False, id=course_id).first()
        if course:
            teachers = Teacher.objects.only('name').filter(is_delete=False)
            categories = CourseCategory.objects.only('name').filter(is_delete=False)
            return render(request, 'admin/course/courses_pub.html', locals())
        else:
            raise Http404('需要更新的课程不存在！')

    def delete(self, request, course_id):
        change_info(request)
        course = Course.objects.filter(is_delete=False, id=course_id).first()
        if course:
            course.is_delete = True
            course.save(update_fields=['is_delete'])
            return to_json_data(errmsg="课程删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的课程不存在")

    def put(self, request, course_id):
        change_info(request)
        course = Course.objects.filter(is_delete=False, id=course_id).first()
        if not course:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的课程不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        form = forms.CoursesPubForm(data=dict_data)
        if form.is_valid():
            for attr, value in form.cleaned_data.items():
                setattr(course, attr, value)

            course.save()
            return to_json_data(errmsg='课程更新成功')
        else:
            # 定义一个错误信息列表
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)


class CoursesPubView(PermissionRequiredMixin, View):
    """
    route: /admin/courses/pub/
    """
    permission_required = ('course.add_course', 'course.view_course')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(CoursesPubView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        teachers = Teacher.objects.only('name').filter(is_delete=False)
        categories = CourseCategory.objects.only('name').filter(is_delete=False)
        return render(request, 'admin/course/courses_pub.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        dict_data = json.loads(json_data.decode('utf8'))

        form = forms.CoursesPubForm(data=dict_data)
        if form.is_valid():
            courses_instance = form.save()
            return to_json_data(errmsg='课程发布成功')
        else:
            # 定义一个错误信息列表
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)


class GroupsManageView(PermissionRequiredMixin, View):
    """
    route: /admin/groups/
    """
    permission_required = ('auth.add_group', 'auth.view_group')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(GroupsManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        groups = Group.objects.values('id', 'name').annotate(num_users=Count('user')).\
            order_by('-num_users', 'id')
        return render(request, 'admin/user/groups_manage.html', locals())


class GroupsEditView(PermissionRequiredMixin, View):
    """
    route: /admin/groups/<int:group_id>/
    """
    permission_required = ('auth.change_group', 'auth.delete_group')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(GroupsEditView, self).handle_no_permission()

    def get(self, request, group_id):
        change_info(request)
        """
        """
        group = Group.objects.filter(id=group_id).first()
        if group:
            permissions = Permission.objects.only('id').all()
            return render(request, 'admin/user/groups_add.html', locals())
        else:
            raise Http404('需要更新的组不存在！')

    def delete(self, request, group_id):
        change_info(request)
        group = Group.objects.filter(id=group_id).first()
        if group:
            group.permissions.clear()   # 清空权限
            group.delete()
            return to_json_data(errmsg="用户组删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的用户组不存在")

    def put(self, request, group_id):
        change_info(request)
        group = Group.objects.filter(id=group_id).first()
        if not group:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的用户组不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        # 取出组名，进行判断
        group_name = dict_data.get('name', '').strip()
        if not group_name:
            return to_json_data(errno=Code.PARAMERR, errmsg='组名为空')

        if group_name != group.name and Group.objects.filter(name=group_name).exists():
            return to_json_data(errno=Code.DATAEXIST, errmsg='组名已存在')

        # 取出权限
        group_permissions = dict_data.get('group_permissions')
        if not group_permissions:
            return to_json_data(errno=Code.PARAMERR, errmsg='权限参数为空')

        try:
            permissions_set = set(int(i) for i in group_permissions)
        except Exception as e:
            logger.info('传的权限参数异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='权限参数异常')

        all_permissions_set = set(i.id for i in Permission.objects.only('id'))
        if not permissions_set.issubset(all_permissions_set):
            return to_json_data(errno=Code.PARAMERR, errmsg='有不存在的权限参数')

        existed_permissions_set = set(i.id for i in group.permissions.all())
        if group_name == group.name and permissions_set == existed_permissions_set:
            return to_json_data(errno=Code.DATAEXIST, errmsg='用户组信息未修改')
        # 设置权限
        for perm_id in permissions_set:
            p = Permission.objects.get(id=perm_id)
            group.permissions.add(p)
        group.name = group_name
        group.save()
        return to_json_data(errmsg='组更新成功！')


class GroupsAddView(PermissionRequiredMixin, View):
    """
    route: /admin/groups/add/
    """
    permission_required = ('auth.add_group', 'auth.view_group')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(GroupsAddView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        permissions = Permission.objects.only('id').all()

        return render(request, 'admin/user/groups_add.html', locals())

    def post(self, request):
        change_info(request)
        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        dict_data = json.loads(json_data.decode('utf8'))

        # 取出组名，进行判断
        group_name = dict_data.get('name', '').strip()
        if not group_name:
            return to_json_data(errno=Code.PARAMERR, errmsg='组名为空')

        one_group, is_created = Group.objects.get_or_create(name=group_name)
        if not is_created:
            return to_json_data(errno=Code.DATAEXIST, errmsg='组名已存在')

        # 取出权限
        group_permissions = dict_data.get('group_permissions')
        if not group_permissions:
            return to_json_data(errno=Code.PARAMERR, errmsg='权限参数为空')

        try:
            # [10, 2, 3, 10, 3, 2, 4]
            permissions_set = set(int(i) for i in group_permissions)
        except Exception as e:
            logger.info('传的权限参数异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='权限参数异常')

        all_permissions_set = set(i.id for i in Permission.objects.only('id'))
        if not permissions_set.issubset(all_permissions_set):
            return to_json_data(errno=Code.PARAMERR, errmsg='有不存在的权限参数')

        # 设置权限
        for perm_id in permissions_set:
            p = Permission.objects.get(id=perm_id)
            one_group.permissions.add(p)

        one_group.save()
        return to_json_data(errmsg='组创建成功！')


class UsersManageView(PermissionRequiredMixin, View):
    """
    route: /admin/users/
    """
    permission_required = ('users.add_users', 'users.view_users')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(UsersManageView, self).handle_no_permission()

    def get(self, request):
        change_info(request)
        users = Users.objects.select_related('idcn').only('idcn_id','username', 'is_staff', 'is_superuser','first_name').filter(is_active=True)
        return render(request, 'admin/user/users_manage.html', locals())


class UsersEditView(PermissionRequiredMixin, View):
    """
    route: /admin/users/<int:user_id>/
    """
    permission_required = ('users.change_users', 'users.delete_users')
    raise_exception = True

    def handle_no_permission(self):
        if self.request.method.lower() != 'get':
            return to_json_data(errno=Code.ROLEERR, errmsg='没有操作权限')
        else:
            return super(UsersEditView, self).handle_no_permission()

    def get(self, request, user_id):
        change_info(request)
        user_instance = Users.objects.filter(id=user_id).first()
        if user_instance:
            groups = Group.objects.only('name').all()
            return render(request, 'admin/user/users_edit.html', locals())
        else:
            raise Http404('需要更新的用户不存在！')

    def delete(self, request, user_id):
        change_info(request)
        user_instance = Users.objects.filter(id=user_id).first()
        if user_instance:
            user_instance.groups.clear()    # 清除用户组
            user_instance.user_permissions.clear()  # 清除用户权限
            user_instance.is_active = False  # 设置为不激活状态
            user_instance.save()
            return to_json_data(errmsg="用户删除成功")
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg="需要删除的用户不存在")

    def put(self, request, user_id):
        change_info(request)
        user_instance = Users.objects.filter(id=user_id).first()
        if not user_instance:
            return to_json_data(errno=Code.NODATA, errmsg='需要更新的用户不存在')

        json_data = request.body
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])
        # 将json转化为dict
        dict_data = json.loads(json_data.decode('utf8'))

        # 取出参数，进行判断
        try:
            groups = dict_data.get('groups')    # 取出用户组列表

            is_staff = int(dict_data.get('is_staff'))
            is_superuser = int(dict_data.get('is_superuser'))
            is_active = int(dict_data.get('is_active'))
            email_active = int(dict_data.get('email_active'))
            if dict_data["Passwd"]:
                form = SuperForm(data=dict_data)

                if form.is_valid():
                    Passwd = make_password(form.cleaned_data.get('Passwd'))
                    user_instance.password = Passwd
            Jfname = dict_data["Jfname"]
            user_instance.first_name = Jfname

            params = [is_staff, is_superuser, is_active, email_active]
            if not all([p in (0, 1) for p in params]):
                return to_json_data(errno=Code.PARAMERR, errmsg='参数错误')
        except Exception as e:
            logger.info('从前端获取参数出现异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='参数错误')

        try:
            groups_set = set(int(i) for i in groups) if groups else set()
        except Exception as e:
            logger.info('传的用户组参数异常：\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='用户组参数异常')

        all_groups_set = set(i.id for i in Group.objects.only('id'))
        if not groups_set.issubset(all_groups_set):
            return to_json_data(errno=Code.PARAMERR, errmsg='有不存在的用户组参数')

        gs = Group.objects.filter(id__in=groups_set)
        # 先清除组
        user_instance.groups.clear()
        user_instance.groups.set(gs)

        user_instance.is_staff = bool(is_staff)
        user_instance.is_superuser = bool(is_superuser)
        user_instance.is_active = bool(is_active)
        user_instance.email_active = bool(email_active)
        user_instance.save()
        return to_json_data(errmsg='用户信息更新成功！')
